<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>lib/LabelElement.js - Documentation</title>

    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="LabelElement.html">LabelElement</a></li><li><a href="module-labeling-utils-GridPolygon.html">GridPolygon</a></li><li><a href="module-mgrs-utils-NonPolarGridZone.html">NonPolarGridZone</a><ul class='methods'><li data-type='method'><a href="module-mgrs-utils-NonPolarGridZone.html#toPolygon">toPolygon</a></li><li data-type='method'><a href="module-mgrs-utils-NonPolarGridZone.html#toPolyline">toPolyline</a></li></ul></li><li><a href="module-mgrs-utils-VisibleGridZone.html">VisibleGridZone</a><ul class='methods'><li data-type='method'><a href="module-mgrs-utils-VisibleGridZone.html#getCenterLabel">getCenterLabel</a></li><li data-type='method'><a href="module-mgrs-utils-VisibleGridZone.html#getLabels">getLabels</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-constants.html">constants</a></li><li><a href="module-geometry-utils.html">geometry-utils</a><ul class='methods'><li data-type='method'><a href="module-geometry-utils.html#~extentToPolygon">extentToPolygon</a></li><li data-type='method'><a href="module-geometry-utils.html#~pointToGeographic">pointToGeographic</a></li><li data-type='method'><a href="module-geometry-utils.html#~polygonToPolyline">polygonToPolyline</a></li><li data-type='method'><a href="module-geometry-utils.html#~toGeographic">toGeographic</a></li><li data-type='method'><a href="module-geometry-utils.html#~toWebMercator">toWebMercator</a></li></ul></li><li><a href="module-labeling-utils.html">labeling-utils</a><ul class='methods'><li data-type='method'><a href="module-labeling-utils.html#~distanceFromMapEdge">distanceFromMapEdge</a></li><li data-type='method'><a href="module-labeling-utils.html#~getScreenSize">getScreenSize</a></li><li data-type='method'><a href="module-labeling-utils.html#~getWidthOfText">getWidthOfText</a></li><li data-type='method'><a href="module-labeling-utils.html#~padZero">padZero</a></li><li data-type='method'><a href="module-labeling-utils.html#~screenDistanceBetweenPoints">screenDistanceBetweenPoints</a></li></ul></li><li><a href="module-mgrs-utils.html">mgrs-utils</a><ul class='methods'><li data-type='method'><a href="module-mgrs-utils.html#~getInterval">getInterval</a></li><li data-type='method'><a href="module-mgrs-utils.html#~handle100kGrids">handle100kGrids</a></li><li data-type='method'><a href="module-mgrs-utils.html#~handleIntervals">handleIntervals</a></li><li data-type='method'><a href="module-mgrs-utils.html#~handleZonePolygon">handleZonePolygon</a></li><li data-type='method'><a href="module-mgrs-utils.html#~processZonePolygons">processZonePolygons</a></li><li data-type='method'><a href="module-mgrs-utils.html#~zonesFromExtent">zonesFromExtent</a></li></ul></li></ul><h3>Externals</h3><ul><li><a href="external-Color.html">Color</a></li><li><a href="external-Extent.html">Extent</a></li><li><a href="external-Font.html">Font</a></li><li><a href="external-Geometry.html">Geometry</a></li><li><a href="external-Graphic.html">Graphic</a></li><li><a href="external-GraphicsLayer.html">GraphicsLayer</a></li><li><a href="external-Map.html">Map</a></li><li><a href="external-Point.html">Point</a></li><li><a href="external-Polygon.html">Polygon</a></li><li><a href="external-Polyline.html">Polyline</a></li><li><a href="external-SpatialReference.html">SpatialReference</a></li><li><a href="external-TextSymbol.html">TextSymbol</a></li></ul>
</nav>

<div id="main">
    
    <h1 class="page-title">lib/LabelElement.js</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 *  @fileOverview Module containing labeling utilities used by GridOverlay widgets.
 *  @author Esri
 *
 * @todo  Review, add and cleanup the code comments (including JSDoc comments)
 */

define([
  "dojo/_base/declare",
  "./mgrs",
  "./geometry-utils",
  "./labeling-utils",
  "esri/geometry/geometryEngine",
  "esri/geometry/screenUtils",
  "esri/graphic",
  "esri/geometry/Point",
  "esri/geometry/Polyline",
  "esri/geometry/Extent",
  "esri/symbols/Font",
  "esri/symbols/SimpleLineSymbol",
  "esri/symbols/TextSymbol",
  "esri/Color"
], function(
  declare,
  mgrs,
  gridGeomUtils,
  gridLabelUtils,
  geometryEngine,
  screenUtils,
  Graphic,
  Point,
  Polyline,
  Extent,
  Font,
  SimpleLineSymbol,
  TextSymbol,
  Color
) {

  /**
   * An object that contains arguments used during labeling, allowing objects to be passed by reference
   * @typedef module:labeling-utils~LabelParameters
   * @property {Number} xOffset         The &lt;em>x&lt;/em> offset
   * @property {Number} yOffset         The &lt;em>y&lt;/em> offset
   * @property {Number} rotation        The text rotation in degrees clockwise (must be an increment of 90°). 0 = Horizontal
   * @property {external:Color}         The color of the label text
   * @property {String} fontFamily      The font-family of the text
   * @property {Number|String} fontSize The css font size (if Number, then "px" units are assumed)
   */
  // labelParameters = {
  //   xOffset: 0,
  //   yOffset: 0,
  //   rotation: 0,
  //   color: null,
  //   fontFamily: "",
  //   fontSize: ""
  // };

  /**
   * @class LabelElement
   * @classdesc Used to determine screen size and position of text labels before they are added to the map.
   *
   * @constructor
   * @param {Object} properties               The LabelElement constructor takes an object as described below
   * @param {external:Map} properties.map     The Map object that is tied to the Grid Overlay
   * @param {external:Point} properties.point The geometry Point object where the label will be placed
   * @param {module:labeling-utils~LabelParameters} properties.labelParameters An object holding all the label parameters
   * @param {String} properties.text                        The label text
   * @param {external:Color} properties.color               The color of the text label
   * @param {String} [properties.verticalAlign="center"]    The vertical alignment "&lt;bottom | lower | middle | center | upper|top>"
   * @param {String} [properties.horizontalAlign="middle"]  The vertical alignment "&lt;left | middle | center | right>"
   *
   * @todo  Review, add and cleanup the code comments (including JSDoc comments)
   */
  return declare(null,  /** @lends module:labeling-utils~LabelElement# */{
    /** The Map object that is tied to the Grid Overlay
     * @type {external:Map}
     */
    "map": null,
    "point": null,
    "xOffset" : 0,
    "yOffset" : 0,
    "text": "",
    "verticalAlign": "", // "&lt;bottom|lower | middle|center | upper|top>"
    "horizontalAlign": "", // "&lt;left | middle|center | right>"
    "rotation": 0, // must be a multiple of 90
    "color": null,
    "fontFamily" : "",
    "fontSize" : 0,
    "font": null,
    constructor: function(args) {
      this.map = args.map;
      this.point = args.point;
      this.xOffset = args.labelParameters.xOffset || 0;
      this.yOffset = args.labelParameters.yOffset || 0;
      this.text = args.text;
      this.verticalAlign = args.verticalAlign || "bottom";
      this.verticalAlign.toLowerCase();
      this.horizontalAlign = args.horizontalAlign || "middle";
      this.horizontalAlign.toLowerCase();
      this.rotation = args.labelParameters.rotation || 0;
      this.rotation = Math.round(this.rotation / 90) * 90;
      this.color = args.labelParameters.color;
      this.font = new Font()
      .setFamily(args.labelParameters.fontFamily || "Arial, Helvetica, sans-serif")
      .setSize(args.labelParameters.fontSize || 0)
      .setWeight(Font.WEIGHT_BOLD);
    },
    getPixelWidth: function() {
      var vertical = this.rotation % 180 !== 0;
      if (vertical) {
        return this.font.size;
      } else {
        return gridLabelUtils.getWidthOfText(this.text, this.font.family, this.font.size);
      }
    },
    getPixelHeight: function() {
      var vertical = this.rotation % 180 !== 0;
      if (vertical) {
        return gridLabelUtils.getWidthOfText(this.text, this.font.family, this.font.size);
      } else {
        return this.font.size;
      }
    },
    decreaseFontSize: function(increment) {
      if (this.font.size === 0) {return;}
      increment = increment || 1;
      this.font.setSize(this.font.size - increment);
      this.setExtent();
    },
    setExtent: function() {
      var map = this.map;
      var referenceScreenPoint = map.toScreen(this.point)
      ;//.offset(this.xOffset, this.yOffset);
      var width = this.getPixelWidth();
      var height = this.getPixelHeight()/1.3333;
      var xmin, ymin, xmax, ymax, extent;

      switch(this.horizontalAlign) {
        case "left":
            referenceScreenPoint = referenceScreenPoint.offset(this.xOffset, 0);
            xmin = referenceScreenPoint.x;
            xmax = referenceScreenPoint.x + width;
            break;
        case "middle":
        case "center":
            xmin = referenceScreenPoint.x - width / 2;
            xmax = referenceScreenPoint.x + width / 2;
            break;
        case "right":
            referenceScreenPoint = referenceScreenPoint.offset(-this.xOffset, 0);
            xmin = referenceScreenPoint.x - width;
            xmax = referenceScreenPoint.x;
            break;
      }

      switch(this.verticalAlign) {
        case "bottom":
        case "lower":
            referenceScreenPoint = referenceScreenPoint.offset(0, -this.yOffset);
            ymin = referenceScreenPoint.y;
            ymax = referenceScreenPoint.y - height;
            break;
        case "middle":
        case "center":
            ymin = referenceScreenPoint.y + height / 2;
            ymax = referenceScreenPoint.y - height / 2;
            break;
        case "upper":
        case "top":
            referenceScreenPoint = referenceScreenPoint.offset(0, this.yOffset);
            ymin = referenceScreenPoint.y + height;
            ymax = referenceScreenPoint.y;
            break;
      }
      extent = new Extent({
        "xmin": xmin,
        "ymin": ymin,
        "xmax": xmax,
        "ymax": ymax
      });
      this.extent = gridGeomUtils.toWebMercator(screenUtils.toMapGeometry(map.extent, map.width, map.height, extent));
    },
    getExtent: function() {
      if (!this.extent) {
        this.setExtent();
      }
      return this.extent;
    },
    fitsInPolygon: function(polygon) {
      var extent = this.getExtent();
      extent = gridGeomUtils.toWebMercator(extent);
      polygon = gridGeomUtils.toWebMercator(polygon);
      return geometryEngine.contains(polygon, extent);
    },
    fitsInExtent: function(testExtent) {
      var extent = this.getExtent();
      extent = gridGeomUtils.toWebMercator(extent);
      testExtent = gridGeomUtils.toWebMercator(testExtent);
      return geometryEngine.contains(testExtent, extent);
    },
    shrinkToFit: function(geometry, minSize) {
      minSize = minSize || 0;
      if (!this.fitsInPolygon(geometry) &amp;&amp; this.font.size > 0) {
        // if (this.xOffset > 0) {this.xOffset -= 1;}
        // if (this.yOffset > 0) {this.yOffset -= 1;}
        this.font.setSize(this.font.size - 1);
        if (this.font.size &lt; minSize) {
          this.font.setSize(0);
        }
        this.setExtent();
        this.shrinkToFit(geometry, minSize);
      }
    },
    getLabelGraphic: function() {
      var textSymbol = new TextSymbol(this.text)
      .setColor(this.color)
      .setAlign(TextSymbol.ALIGN_START)
      .setFont(this.font);
      var extent = this.getExtent();
      var labelPoint = this.map.toScreen(this.point);
      var offsetPoint = this.map.toScreen(new Point([extent.xmin, extent.ymin], extent.spatialReference));
      textSymbol.setOffset(offsetPoint.x - labelPoint.x, -(offsetPoint.y - labelPoint.y));
      return new Graphic(this.point, textSymbol);
    }
  });
});</code></pre>
        </article>
    </section>




</div>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>
